import * as THREE from 'three';

// scene场景的公共内容
export const createEarth = collect => {
  const earth = collect.createEarth({ position: { x: -15, y: -1 } });
  // 这里注意路径的填写：打包后是 main.js 和 assets 文件夹在同一目录下，所以引用时要用 './'
  // 这里用 '../' 也可以的原因是，ThreeJS内部加载路径时用了寻址的方法
  const machine = collect.createMachine('./images/3d/move.png', {
    position: { x: 15, z: -20, y: -5 }
  });
  collect.groupCommon = { earth, machine };
};

export const createShelf = () => {};

export const createAureole = (radius, height, color) => {
  let geo, mat;
  let segment = 4;

  //geo
  {
    let bottomPos = [];
    let topPos = [];
    let angleOffset = (Math.PI * 2) / segment;
    for (let i = 0; i < segment; i++) {
      let x = Math.cos(angleOffset * i) * radius;
      let z = Math.sin(angleOffset * i) * radius;
      bottomPos.push(x, 0, z);
      topPos.push(x, height, z);
    }
    //
    bottomPos = bottomPos.concat(topPos);

    let face = [];
    for (let i = 0; i < segment; i++) {
      if (i !== segment - 1) {
        face.push(i + segment + 1, i, i + segment);
        face.push(i, i + segment + 1, i + 1);
      } else {
        face.push(segment, i, i + segment);
        face.push(i, segment, 0);
      }
    }

    geo = new THREE.BufferGeometry();
    geo.setAttribute(
      'position',
      new THREE.BufferAttribute(new Float32Array(bottomPos), 3)
    );
    geo.setIndex(new THREE.BufferAttribute(new Uint16Array(face), 1));
  }

  //mat
  {
    let c = new THREE.Color(color);
    mat = new THREE.ShaderMaterial({
      uniforms: {
        targetColor: { value: new THREE.Vector3(c.r, c.g, c.b) },
        height: { value: height }
      },
      side: THREE.DoubleSide,
      transparent: true,
      //depthTest:false,
      depthWrite: false,
      vertexShader: [
        'varying vec3 modelPos;',
        'void main() {',
        '   modelPos = position;',
        '	gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0 );',
        '}'
      ].join('\n'),
      fragmentShader: [
        'uniform vec3 targetColor;',
        'uniform float height;',
        'varying vec3 modelPos;',

        'void main() {',
        '   gl_FragColor = vec4(targetColor.xyz, (1.0 - modelPos.y/height)*(1.0 - modelPos.y/height));',
        '}'
      ].join('\n')
    });
  }

  let mesh = new THREE.Mesh(geo, mat);
  // mesh.renderOrder = 9999;
  return mesh;
};

export const addFlightCircle = radius => {
  // 创建光圈材质
  const circleMaterial = new THREE.ShaderMaterial({
    transparent: false,
    depthWrite: false,
    uniforms: {
      color: { value: new THREE.Color(0x8888ff) }, // 颜色
      center: { value: new THREE.Vector3(0, 0, 0) }, // 光圈中心位置
      radius: { value: 1.0 } // 光圈半径
    },
    vertexShader: `
      varying vec3 vPosition;
      void main() {
        vPosition = position;
        gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
      }`,
    fragmentShader: `
      uniform vec3 color;
      uniform vec3 center;
      uniform float radius;
      varying vec3 vPosition;
      void main() {
        float distance = length(vPosition - center);
        float intensity = 1.0 - (distance / radius); // 调整扩散效果
        gl_FragColor = vec4(color * intensity, 1.0);
      }`
  });

  // 创建光圈几何体（这里使用一个平面表示）
  const circleGeometry = new THREE.PlaneGeometry(5, 5, 1, 1); // 调整大小以适应你的需求
  const circleMesh = new THREE.Mesh(circleGeometry, circleMaterial);
  circleMesh.rotation.x = -Math.PI / 2;

  return circleMesh;
};

export const createGood = (goodsSize, palletPlaneSize, palletRackSize) => {
  let goodsMesh = new THREE.Group();

  let singleBox = new THREE.BoxGeometry(goodsSize.x, goodsSize.y, goodsSize.z);
  let boxTextureUp = new THREE.TextureLoader().load('./warehouse/goods.png');
  let boxTextureEmpty = new THREE.TextureLoader().load(
    './warehouse/goodsEmpty.png'
  );
  // boxTexture.wrapS = THREE.RepeatWrapping;
  // boxTexture.wrapT = THREE.RepeatWrapping;
  // boxTexture.repeat.set(0.5, 0.5);
  boxTextureUp.needsUpdate = false;
  boxTextureEmpty.needsUpdate = false;

  let boxMaterialUp = new THREE.MeshBasicMaterial({
    map: boxTextureUp,
    transparent: true
  });
  let boxMaterialEmpty = new THREE.MeshBasicMaterial({
    map: boxTextureEmpty,
    transparent: true
  });

  let boxMesh = new THREE.Mesh(singleBox, [
    boxMaterialUp,
    boxMaterialUp,
    boxMaterialEmpty,
    boxMaterialEmpty,
    boxMaterialUp,
    boxMaterialUp
  ]);
  boxMesh.receiveShadow = true;

  boxMesh.position.set(
    0,
    goodsSize.y / 2 + palletPlaneSize.y + palletRackSize.y,
    0
  );

  goodsMesh.add(boxMesh);

  const palletMaterial = new THREE.MeshPhongMaterial({ color: 'grey' });

  const palletPlaneGeometry = new THREE.BoxGeometry(
    palletPlaneSize.z,
    palletPlaneSize.y,
    palletPlaneSize.z
  );
  const palletPlaneMesh = new THREE.Mesh(palletPlaneGeometry, palletMaterial);

  const palletRackGeometry = new THREE.BoxGeometry(
    palletRackSize.x,
    palletRackSize.y,
    palletRackSize.z
  );
  const palletRackMesh = new THREE.Mesh(palletRackGeometry, palletMaterial);

  let palletTop = palletPlaneMesh.clone();
  palletTop.position.y = palletRackSize.y + palletPlaneSize.y * 1.5;
  goodsMesh.add(palletTop);
  goodsMesh.add(palletPlaneMesh);

  let leftBottom = palletRackMesh.clone();
  leftBottom.position.set(
    -palletPlaneSize.x / 2 + palletRackSize.x / 2,
    palletPlaneSize.y + palletRackSize.y / 2,
    palletPlaneSize.z / 2 - palletRackSize.z / 2
  );
  goodsMesh.add(leftBottom);

  let rightBottom = palletRackMesh.clone();
  leftBottom.position.set(
    palletPlaneSize.x / 2 - palletRackSize.x / 2,
    palletPlaneSize.y + palletRackSize.y / 2,
    palletPlaneSize.z / 2 - palletRackSize.z / 2
  );
  goodsMesh.add(rightBottom);

  let leftTop = palletRackMesh.clone();
  leftBottom.position.set(
    -palletPlaneSize.x / 2 + palletRackSize.x / 2,
    palletPlaneSize.y + palletRackSize.y / 2,
    -palletPlaneSize.z / 2 + palletRackSize.z / 2
  );
  goodsMesh.add(leftTop);

  let rightTop = palletRackMesh.clone();
  leftBottom.position.set(
    palletPlaneSize.x / 2 - palletRackSize.x / 2,
    palletPlaneSize.y + palletRackSize.y / 2,
    -palletPlaneSize.z / 2 + palletRackSize.z / 2
  );
  goodsMesh.add(rightTop);

  return goodsMesh;
};

export const initGoodsStack = layout => {
  const goodsSize = new THREE.Vector3(1, 1, 1);
  const palletPlaneSize = new THREE.Vector3(1.1, 0.02, 1.1);
  const palletRackSize = new THREE.Vector3(0.04, 0.06, 0.04);

  let goodsMesh = createGood(goodsSize, palletPlaneSize, palletRackSize);
  let startRow = 5;
  let startCol = 0;
  let goodsGroup = new THREE.Group();

  for (let row = 0; row < layout[0]; row++) {
    for (let col = 0; col < layout[1]; col++) {
      let cloneGoods = goodsMesh.clone();
      cloneGoods.position.set(
        startRow + row * (goodsSize.x + 0.09),
        0,
        startCol + col * (goodsSize.z + 0.1)
      );
      goodsGroup.add(cloneGoods);
    }
  }

  return goodsGroup;
};
